﻿using System;
using System.Linq;
using Loki.Model;
using NUnit.Framework;
using Loki.Engine;

namespace Loki.Core.Model.Test
{
    [TestFixture]
    public class IndexKeyMapperTest : AssertionHelper
    {
        private IndexedKeyMapper<DummyEntity, int> _Mapper;
        private IndexedKeyMapper<DummyEntity, string> _StringMapper;

        private DummyEntity _Entity;
        private DummyEntity _Entity2;
        private DummyEntity _Entity3;
        private DummyEntity _Entity4;
        private DummyEntity _Entity5;
        private DummyEntity _Entity6;

        [SetUp]
        public void SetUp()
        {
            _Mapper = new IndexedKeyMapper<DummyEntity, int>(new IndexConfiguration<DummyEntity, int>() { Indexer = x => x.Key1 }, new EntityEqualityComparer<DummyEntity, Guid>());
            _StringMapper = new IndexedKeyMapper<DummyEntity, string>(new IndexConfiguration<DummyEntity, string>() { Indexer = x => x.Key2, IndexComparer = StringComparer.InvariantCultureIgnoreCase });

            _Entity = new DummyEntity() { ID = Guid.NewGuid(), Key1 = 1, Key2 = "a", Value = "gnagna" };
            _Entity2 = new DummyEntity() { ID = Guid.NewGuid(), Key1 = 2, Key2 = "b", Value = "gnagna" };
            _Entity3 = new DummyEntity() { ID = Guid.NewGuid(), Key1 = 1, Key2 = "c", Value = "gnagna" };
            _Entity4 = new DummyEntity() { ID = Guid.NewGuid(), Key1 = 1, Key2 = "d", Value = "gnagna" };
            _Entity5 = new DummyEntity() { ID = _Entity3.ID, Key1 = 1, Value = "gnagna", Key2 = "d" };
            _Entity6 = new DummyEntity() { ID = _Entity3.ID, Key1 = 3, Value = "gnagna", Key2 = "d" };

            _Mapper.Register(_Entity);
            _Mapper.Register(_Entity2);
            _Mapper.Register(_Entity3);

            _StringMapper.Register(_Entity3);
            _StringMapper.Register(_Entity2);
            _StringMapper.Register(_Entity);
        }

        [Test]
        public void TestRegisterAdd()
        {
            Expect(_Mapper.Register(_Entity4),
                Is.True
                );
        }

        [Test]
        public void TestRegisterReplace()
        {
            Expect(_Mapper.Register(_Entity5),
                Is.False
                );
        }

        [Test]
        public void TestRegisterReplaceWithKeyChange()
        {
            Expect(_Mapper.Register(_Entity6),
                Is.True
                );
        }

        [Test]
        public void TestGet()
        {
            Expect(_Mapper.GetAllByKey(1).Count(),
                EqualTo(2)
                );
        }

        [Test]
        public void TestGetWithComparer()
        {
            Expect(_StringMapper.GetAllByKey("B").Count(),
                EqualTo(1)
                );
        }

        [Test]
        public void TestIsLoadedTrue()
        {
            _Mapper.MarkAsLoaded(1);
            Expect(_Mapper.IsLoaded(1),
                Is.True
                );
        }

        [Test]
        public void TestIsLoadedFalse()
        {
            Expect(_Mapper.IsLoaded(1),
                Is.False
                );
        }


        [Test]
        public void TestIsLoadedWithComparer()
        {
            _StringMapper.MarkAsLoaded("b");
            Expect(_StringMapper.IsLoaded("B"),
                Is.True
                );
        }

        [Test]
        public void TestGetAllBy()
        {
            Expect(_Mapper.GetAllByKey(2).First(),
                EqualTo(_Entity2)
                );
        }

        [Test]
        public void TestUnregister()
        {
            _Mapper.Remove(_Entity);
            Expect(_Mapper.GetAllByKey(1).Count(),
                 EqualTo(1)
                 );
        }
    }
}
